package com.ruoyi.system.service.impl;

import java.util.Base64;
import java.util.Date;
import java.util.List;

import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.system.amqp.taskscheduler.RedisCacheUpdateTask;
import com.ruoyi.system.domain.LineProduction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.LineDeviceMapper;
import com.ruoyi.system.domain.LineDevice;
import com.ruoyi.system.service.ILineDeviceService;
import com.ruoyi.system.amqp.AmqpMessagePub;
import org.springframework.core.task.TaskExecutor;

import com.ruoyi.system.amqp.ProductMatcher;

/**
 * 设备deviceService业务层处理
 * 
 * @author ruoyi
 * @date 2024-06-14
 */
@Service
public class LineDeviceServiceImpl implements ILineDeviceService 
{
    @Autowired
    private LineDeviceMapper lineDeviceMapper;

    @Autowired
    private RedisCacheUpdateTask redisCacheUpdateTask;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ProductMatcher productMatcher;

    private final TaskExecutor taskExecutor;

    @Autowired
    public LineDeviceServiceImpl(TaskExecutor taskExecutor) {
        this.taskExecutor = taskExecutor;
    }
    /**
     * 查询设备device-根据设备主键
     *
     * @param id 设备device主键
     * @return 设备device
     */
    @Override
    public LineDevice selectLineDeviceById(Integer id)
    {
        return lineDeviceMapper.selectLineDeviceById(id);
    }

    /**
     * 查询某房间设备device列表
     *
     * @param lineDevice 包含房间production的设备lineDevice
     * @return 某房间设备device集合
     */
    @Override
    public List<LineDevice> selectLineProductionDevicesByLineDevice(LineDevice lineDevice) {
        return lineDeviceMapper.selectLineProductionDevicesByLineDevice(lineDevice);
    }

    /**
     * 查询设备device-根据设备名称
     *
     * @param name 设备device名称
     * @return 设备device
     */
    @Override
    public LineDevice selectLineDeviceByName(String name)
    {
        if(redisCache.getCacheObject(name)!=null){
            return (LineDevice) redisCacheUpdateTask.getRedisCache(name);
        }
        return lineDeviceMapper.selectLineDeviceByName(name);
    }

    /**
     * 查询设备device上下线时间-根据设备名称-未测试出问题自负
     * 未测试出问题自负
     *
     * @param name 设备device名称
     * @return 设备device上下线时间Date对象
     */
    @Override
    public Date selectLineDeviceStatusTimeByName(String name)
    {
        return lineDeviceMapper.selectLineDeviceStatusTimeByName(name);
    }

    /**
     * 查询删除设备device列表
     *
     * @param lineDevice 设备device
     * @return 设备device
     */
    @Override
    public List<LineDevice> selectLineDeviceDelList(LineDevice lineDevice)
    {
        return lineDeviceMapper.selectLineDeviceDelList(lineDevice);
    }

    /**
     * 查询未删除设备device列表
     * 
     * @param lineDevice 设备device
     * @return 设备device
     */
    @Override
    public List<LineDevice> selectLineDeviceList(LineDevice lineDevice)
    {
        return lineDeviceMapper.selectLineDeviceList(lineDevice);
    }

    /**
     * 给其中一台设备device发送MQTT消息
     *
     * @param lineDevice 设备device
     * @return 结果
     */
    @Override
    public int sendLineDeviceMessage(LineDevice lineDevice, Integer monitorTime, Integer intervalInMs)  {
        String messageContent = lineDevice.getControlMessage();
        String productKey = productMatcher.getProductKey(lineDevice.getType());
        String deviceName = lineDevice.getName();
        Base64.Encoder encoder = Base64.getEncoder();
        messageContent = encoder.encodeToString(messageContent.getBytes());
        if (1 == monitorTime) {
            return new AmqpMessagePub(taskExecutor).publishMessage(productKey, deviceName, messageContent);
        }
        new AmqpMessagePub(taskExecutor).publishManyMessageAsync(productKey, deviceName, messageContent, monitorTime, intervalInMs);
        return 0;
    }

    /**
     * 给产线内所有设备device发送MQTT消息
     *
     * @param lineProduction 产线LineProduction
     * @return 结果
     */
    @Override
    public int sendLineDeviceMessagesByProduction(LineProduction lineProduction, Integer monitorTime, Integer intervalInMs)  {
        LineDevice lineDevice00 = new LineDevice();
        lineDevice00.setId(lineProduction.getId());
        List<LineDevice> lineDevices = lineDeviceMapper.
                selectLineProductionDevicesByLineDevice(lineDevice00);
        for (LineDevice lineDevice : lineDevices) {
            lineDevice.setControlMessage(lineProduction.getControlMessage());
            if(lineDevices.indexOf(lineDevice) == lineDevices.size()-1){
                return sendLineDeviceMessage(lineDevice, monitorTime, intervalInMs);
            }
            sendLineDeviceMessage(lineDevice, monitorTime, intervalInMs);
        }
        return 0;
    }

    /**
     * 新增设备device
     *
     * @param lineDevice 设备device
     * @return 结果
     */
    @Override
    public int insertLineDevice(LineDevice lineDevice)
    {
        return lineDeviceMapper.insertLineDevice(lineDevice);
    }

    /**
     * 修改设备device
     * 
     * @param lineDevice 设备device
     * @return 结果
     */
    @Override
    public int updateLineDevice(LineDevice lineDevice)
    {
        return lineDeviceMapper.updateLineDevice(lineDevice);
    }

    /**
     * 批量删除设备device
     * 
     * @param ids 需要删除的设备device主键
     * @return 结果
     */
    @Override
    public int deleteLineDeviceByIds(Integer[] ids)
    {
        return lineDeviceMapper.deleteLineDeviceByIds(ids);
    }

    /**
     * 删除设备device信息
     * 
     * @param lineDevice 设备device主键
     * @return 结果
     */
    @Override
    public int deleteLineDeviceByLineDevice(LineDevice lineDevice)
    {
        return lineDeviceMapper.deleteLineDeviceByLineDevice(lineDevice);
    }


    /**
     * 恢复设备device
     *
     * @param id 设备device主键
     * @return 结果
     */
    public int restoreLineDeviceById(Integer id){
        return lineDeviceMapper.restoreLineDeviceById(id);
    }

    /**
     * 批量恢复设备device
     *
     * @param ids 需要恢复的数据主键集合
     * @return 结果
     */
    public int restoreLineDeviceByIds(Integer[] ids){
        return lineDeviceMapper.restoreLineDeviceByIds(ids);
    }
}
